package com.dgut.activiti.web;

import java.io.InputStream;
import java.util.zip.ZipInputStream;

import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.dgut.activiti.entity.ProcessDefinitionDTO;
import com.dgut.activiti.service.IActivitiService;
import com.dgut.common.util.ExtAjaxResponse;
import com.dgut.common.util.ExtPageable;


@Controller
@RequestMapping("/activiti")
public class ActivitiController {
	@Autowired
	private IActivitiService activitiService;
	//流程服务
	@Autowired
	private RepositoryService repositoryService;// 提供了管理和控制 流程部署和流程定义的操作。
	
	/**
	 * 1.部署流程
	 */

	@RequestMapping("/deploy")
	public @ResponseBody ExtAjaxResponse deploy(@RequestParam(value = "file", required = true) MultipartFile file) {
		// 获取上传的文件名
		String fileName = file.getOriginalFilename();
		try {
			// 得到输入流（字节流）对象
			InputStream fileInputStream = file.getInputStream();
			// 文件的扩展名
			String extension = FilenameUtils.getExtension(fileName);
			// zip或者bar类型的文件用ZipInputStream方式部署
			DeploymentBuilder deployment = repositoryService.createDeployment();
			if (extension.equals("zip") || extension.equals("bar")) {
				ZipInputStream zip = new ZipInputStream(fileInputStream);
				deployment.addZipInputStream(zip);
			} else {
				// 其他类型的文件直接部署 bpmn
				deployment.addInputStream(fileName, fileInputStream);
			}
			deployment.deploy();
		} catch (Exception e) {
			// logger.error("error on deploy process, because of file input stream");
			return new ExtAjaxResponse(false, "部署失败!");
		}
		return new ExtAjaxResponse(true, "部署成功!");
	}

	/**
	 * 读取流程资源
	 *
	 * @param processDefinitionId
	 *            流程定义ID
	 * @param resourceName
	 *            资源名称
	 */
	@RequestMapping("/readResource")
	public void readResource(@RequestParam("pdid") String processDefinitionId,
			@RequestParam("resourceName") String resourceName, HttpServletResponse response) throws Exception {
		ProcessDefinitionQuery pdq = repositoryService.createProcessDefinitionQuery();
		ProcessDefinition pd = pdq.processDefinitionId(processDefinitionId).singleResult();

		// 通过接口读取
		InputStream resourceAsStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), resourceName);

		// 输出资源内容到相应对象
		byte[] b = new byte[1024];
		int len = -1;
		while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}

	/**
	 * 流程定义列表
	 */
	@RequestMapping(value = "/processList")
	public @ResponseBody Page<ProcessDefinitionDTO> processAjaxList(ExtPageable pageable) {
		Page<ProcessDefinitionDTO> processDefinition = activitiService.processAjaxList(pageable);
		return processDefinition;
	}

	/**
	 * 删除流程定义
	 */
	@RequestMapping(value = "/deleteDeployment")
	public @ResponseBody ExtAjaxResponse deleteProcessDefinition(@RequestParam("deploymentId") String deploymentId) {
		try {
			activitiService.deleteProcessDefinition(deploymentId);
		} catch (Exception e) {
			// logger.error("error on deploy process, because of file input stream");
			return new ExtAjaxResponse(false, "删除失败!");
		}
		return new ExtAjaxResponse(true, "删除成功!");
	}

	/**
     * 5.挂起、激活流程定义
     */
    /*@RequestMapping(value = "/update/{state}/{processDefinitionId}")
    public @ResponseBody AJAXResultMessage updateState(@PathVariable("state") String state, @PathVariable("processDefinitionId") String processDefinitionId) {
    	try {
	    	if (state.equals("active")) {
	            repositoryService.activateProcessDefinitionById(processDefinitionId, true, null);
	        } else if (state.equals("suspend")) {
	            repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
	        }
	    	return new AJAXResultMessage(true,"已"+(state.equals("active")?"激活":"挂起")+"ID为[" + processDefinitionId + "]的流程定义。");
    	} catch (Exception e) {
	        return new AJAXResultMessage(false,"操作失败!");
	    }
    }
    
    *//**
     * 6.流程定义转换为model（在线编辑和部署）
     *//*
    @RequestMapping(value = "/convert-to-model/{processDefinitionId}")
    public @ResponseBody AJAXResultMessage convertToModel(@PathVariable("processDefinitionId") String processDefinitionId){
    	try {
    		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
    		InputStream bpmnStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(),processDefinition.getResourceName());
	        XMLInputFactory xif = XMLInputFactory.newInstance();
	        InputStreamReader in = new InputStreamReader(bpmnStream, "UTF-8");
	        XMLStreamReader xtr = xif.createXMLStreamReader(in);
	        BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);
	        BpmnJsonConverter converter = new BpmnJsonConverter();
	        com.fasterxml.jackson.databind.node.ObjectNode modelNode = converter.convertToJson(bpmnModel);
	        Model modelData = repositoryService.newModel();
	        modelData.setKey(processDefinition.getKey());
	        modelData.setName(processDefinition.getResourceName());
	        modelData.setCategory(processDefinition.getDeploymentId());

	        ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
	        modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processDefinition.getName());
	        modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
	        modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, processDefinition.getDescription());
	        modelData.setMetaInfo(modelObjectNode.toString());

	        repositoryService.saveModel(modelData);
	        repositoryService.addModelEditorSource(modelData.getId(), modelNode.toString().getBytes("utf-8"));
	        
	        return new AJAXResultMessage(true,"转换成功！");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return new AJAXResultMessage(false,"转换失败，转码错误！");
		} catch (XMLStreamException e) {
			e.printStackTrace();
			return new AJAXResultMessage(false,"转换失败，创建XML读取流错误！");
		}
    }*/
}
